package btb.util;

public abstract class AObjectList
{
	public static final int DEFAULT_CAPACITY = 4;
	
	protected Object[] list = null;
	
	protected int count = 0;
	protected int capacity;
	
	public AObjectList()
	{
		this.capacity = DEFAULT_CAPACITY;
		this.list = new Object[DEFAULT_CAPACITY];
	}
	
	public AObjectList(int _capacity)
	{
		this.capacity = _capacity;
		this.list = new Object[this.capacity];
	}
	
	public synchronized void add(Object _object)
	{
		if(this.count == 0)
			this.list = new Object[this.capacity];
		
		if(this.count < this.capacity)
		{
			this.list[this.count] = _object;
			this.count++;
		}
		else
		{
			this.grow();
			this.add(_object);
		}
	}
	
	public synchronized void remove(Object _object)
	{
		int pos = this.find(_object);
		
		if(pos >= 0)
		{
			this.list[pos] = null;
			System.arraycopy(this.list, pos + 1, this.list, pos, this.list.length - pos - 1);
			this.count--;
		}
	}
	
	public synchronized void removeByIndex(int _pos)
	{
		if(_pos < this.capacity && _pos > -1)
		{
			this.list[_pos] = null;
			System.arraycopy(this.list, _pos + 1, this.list, _pos, this.list.length - _pos - 1);
			this.count--;
		}
	}
	
	protected void grow()
	{
		this.capacity = this.capacity * 2;
		
		Object[] tmplist = this.getList();
		this.list = new Object[this.capacity];
		
		if(this.count > 0)
			System.arraycopy(tmplist, 0, this.list, 0, tmplist.length);
	}
	
	public synchronized int find(Object _object)
	{
		for(int i = 0; i < this.count; i++)
			if(this.list[i] == _object)
				return i;
		
		return -1;
	}
	
	public synchronized String toString()
	{
		String tmp;
		String str = "";
		
		str += "Count: " + this.count + "\n";
		str += "Capacity: " + this.capacity + "\n";
		
		if( this.count > 0)
		{
			str += "Objects:\n";
			for(int i = 0; i < this.count; i++)
			{
				str += "[" + i + "]:  " + (tmp = this.list[i].getClass().getName());
				if(tmp.equals("String"))
					str += "  '" + this.list[i] + "'";
				str += "\n";
			}
		}
		else
		{
			str += "<List is empty.>";
		}
		
		return str;
	}
	
	public synchronized Object[] getList()
	{
		Object[] tmpList = new Object[this.count];
		System.arraycopy(this.list, 0, tmpList, 0, this.count);
		return tmpList;
	}
	
	public synchronized Object[] getTrueList()
	{
		return this.list;
	}
	
	public synchronized int getCount()
	{
		return this.count;
	}
	
	public synchronized int getCapacity()
	{
		return this.capacity;
	}
	
	public synchronized boolean isEmpty()
	{
		return this.count == 0;
	}
	
	public synchronized boolean isBlank()
	{
		return this.capacity == 0 && this.list.length == 0;
	}
}
